package ldh.im.fxbase.util;


import javafx.scene.paint.Color;
import ldh.im.fxbase.data.pojo.ImFile;
import ldh.im.fxbase.data.pojo.ImMessage;
import ldh.im.util.ConfigUtil;
import ldh.rpc.util.JsonUtil;
import ldh.im.util.UploadFileUtil;
import org.kordamp.ikonli.javafx.FontIcon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.DecimalFormat;

public class FileUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileUtil.class);
    // 图片后缀
    public static final String IMAGE_SUFFIXS = ",bmp,jpg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,WMF,webp,avif,apng,";
    public static final String AUDIO_SUFFIXS = ",mp3,wma,aac,ogg,wav,flac,ape,midi,cda,au,aiff,mp1,mp2,m4a,";
    public static final String VIDEO_SUFFIXS = ",mp4,";

    // excel后缀
    public static final String EXCEL_SUFFIXS = ",xls,xlsx,csv,";
    // zip后缀
    public static final String ZIP_SUFFIXS = ",zip,rar,7z,tar,gz,";
    // doc后缀
    public static final String DOC_SUFFIXS = ",doc,docx,";
    public static final String PDF_SUFFIXS = ",pdf,";

    public static final String XML_SUFFIXS = ",xml,";

    public static final String TXT_SUFFIXS = ",txt,";
    public static final String HTML_SUFFIXS = ",html,htm,";
    public static final String MD_SUFFIXS = ",md,";

    // ppt后缀
    public static final String PPT_SUFFIXS = ",ppt,pptx,";
    // exe后缀
    public static final String EXE_SUFFIXS = ",exe,bat,";

    public static boolean downFileExisted(ImMessage imMessage) {
        try {
            return Files.exists(Paths.get(imMessage.getContent()));
        } catch (Exception e) {}
        String path = ConfigUtil.getRoot() + imMessage.getMessageExt().getFileUrl();
        return Files.exists(Paths.get(path));
    }

    public static String getFilePath(ImMessage imMessage) {
        String imagePath = checkFilePath(trimPath(imMessage.getContent()));
        imagePath = imagePath == null ? checkFilePath(ConfigUtil.getRoot() + trimPath(imMessage.getContent())) : imagePath;
        imagePath = imagePath == null ? checkFilePath(ConfigUtil.getRoot() + trimPath(imMessage.getMessageExt().getFileUrl())) : imagePath;
        if (imagePath == null) {
            LOGGER.error("文件路径为空, data: {}", JsonUtil.toJson(imMessage));
        }
        return imagePath;
    }

    public static String getLocalFilePath(String filePath) {
        try {
            return new File(filePath).toURI().toURL().toExternalForm();
        } catch (Exception e) {
            LOGGER.error("文件不存在", e);
        }
        return null;
    }

    public static boolean isCollectFile(ImMessage imMessage) {
        if (imMessage.getMessageType().isFile()) {
            return imMessage.getContent().startsWith("/collect") || imMessage.getContent().startsWith("\\collect") ||
                    imMessage.getContent().startsWith("collect");
        }
        return false;
    }

    public static boolean isCaptureFile(ImMessage imMessage) {
        if (imMessage.getMessageType().isFile()) {
            return imMessage.getContent().startsWith("/capture") || imMessage.getContent().startsWith("\\capture") ||
                    imMessage.getContent().startsWith("capture");
        }
        return false;
    }

    public static String getFilePath(ImFile imFile) {
        String imagePath = checkFilePath(trimPath(imFile.getPath()));
        imagePath = imagePath == null ? checkFilePath(ConfigUtil.getRoot() + trimPath(imFile.getPath())) : imagePath;
        return imagePath;
    }

    public static boolean isImage(File file) {
        String suffix = UploadFileUtil.suffix(file.getName());
        return IMAGE_SUFFIXS.contains(suffix.toLowerCase());
    }

    public static boolean isAudio(File file) {
        String suffix = UploadFileUtil.suffix(file.getName());
        return AUDIO_SUFFIXS.contains(suffix.toLowerCase());
    }

    public static boolean isVideo(File file) {
        String suffix = UploadFileUtil.suffix(file.getName());
        return VIDEO_SUFFIXS.contains(suffix.toLowerCase());
    }

    public static boolean isText(File file) {
        String suffix = UploadFileUtil.suffix(file.getName());
        return TXT_SUFFIXS.contains(suffix.toLowerCase());
    }

    public static String checkFilePath(String path) {
        try {
            if (StageUtil.isWindow() && path.startsWith("\\")) {
                return null;
            }
            File file = new File(path);
            if (file.exists()) {
                return path;
            }
        } catch (Exception e) {
            LOGGER.error(String.format("check file path error, path: {}", path), e);
        }
        return null;
    }

    public static long getFileSize(File file) {
        try {
            return Files.size(file.toPath());
        } catch (Exception e){
            LOGGER.error("获取文件大小失败", e);
        }
        return 0L;
    }

    public static boolean isDownloaded(String relaxPath) {
        try {
            String path = ConfigUtil.getRoot() + relaxPath;
            return Files.exists(Paths.get(path));
        } catch (Exception e) {
            return false;
        }
    }

    public static FontIcon getFileIcon(String suffix) {
        String iconName = "fa-file";
        String lowerSuffix = suffix.toLowerCase();
        String containLowerSuffix = "," + lowerSuffix + ",";
        if (TXT_SUFFIXS.contains(containLowerSuffix)) {
            iconName = "fa-file-text-o";
        } else if (EXE_SUFFIXS.contains(containLowerSuffix)) {
            iconName = "fa-file-excel-o";
        } else if (PPT_SUFFIXS.contains(containLowerSuffix)) {
            iconName = "fa-product-hunt";
        } else if (PDF_SUFFIXS.contains(containLowerSuffix)) {
            iconName = "fa-file-pdf-o";
        } else if (DOC_SUFFIXS.contains(containLowerSuffix)) {
            iconName = "fa-file-word-o";
        } else if (AUDIO_SUFFIXS.contains(containLowerSuffix)) {
            iconName = "fa-file-audio-o";
        } else if (VIDEO_SUFFIXS.contains(containLowerSuffix)) {
            iconName = "fa-file-video-o";
        } else if (FileUtil.IMAGE_SUFFIXS.contains(containLowerSuffix)) {
            iconName = "fa-file-picture-o";
        } else if (ZIP_SUFFIXS.contains(containLowerSuffix)) {
            iconName = "fa-file-zip-o";
        }
        return ldh.im.fxbase.util.IconUtil.createIcon(iconName, 18, Color.BLACK);
    }

    public static String formatFileSize(long fileSize) {
        if (fileSize < 0) return "";
        double fsize = fileSize;
        String[] suffixs = new String[]{"B", "K", "M", "G", "T", "P"};
        for(int i=0, lg=suffixs.length; i<lg; i++) {
            if (fsize <= (i+1) * 1024) {
                DecimalFormat decimalFormat = new DecimalFormat("#.0");
                return decimalFormat.format(fsize) + suffixs[i];
            }
            fsize = fsize/1024;
        }
        return "";
    }

    public static boolean isPath(String path) {
        try {
            return Files.exists(Paths.get(path));
        } catch (Exception e) {
            return false;
        }
    }

    public static void openFileDirCommand(String dir) {
        String command = "";
        if (StageUtil.isMac()) {
            command = String.format("open %s", dir);
        } else if (StageUtil.isWindow()) {
            command = String.format("explorer %s", dir);
        }  else if (StageUtil.isLinux()) {
            command = String.format("explorer %s", dir);
            command = null;
            // todo
        } else {
            throw new RuntimeException("系统不支持");
        }

        try {
            Runtime.getRuntime().exec(command);
        } catch (Exception e) {
            LOGGER.error("打开目录失败", e);
        }
    }

    public static String getSuffix(String fileName) {
        String suffix = "";
        int index = fileName.lastIndexOf(".");
        if (index > 0) {
            suffix = fileName.substring(index+1);
            suffix = suffix.toLowerCase();
        } else {
            throw new RuntimeException("文件必须要有后缀");
        }
        return suffix;
    }

    public static int[] getImageSize(File imageFile) {
        try {
            BufferedImage bufferedImage = ImageIO.read(imageFile);
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            return new int[] {width, height};
        } catch (Exception e) {
            LOGGER.error(imageFile.getPath() + "获取图片尺寸有误", e);
        }
        return null;
    }

    private static String trimPath(String path) {
        long time = System.currentTimeMillis();
        if (path.startsWith("file:\\")) {
            path = path.substring(5);
        }
        LOGGER.info("trim time {}", System.currentTimeMillis() - time);
        return path;
    }

}
